<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>正则表达式</title>
    <link rel="stylesheet" href="../css/common.css">
    <link rel="stylesheet" href="../css/html.css">
</head>
<body>
<div class="container">
    <div class="catalogue">
        <div><a href="#js_base">正则表达式</a></div>

    </div>
    <div class="substance">
        <div class="one">
            <h1 id="js_base">正则表达式</h1>
            <pre class="bj">
正则表达式能做什么: 1、查找特定字符   2、替换文本(eg.敏感词过滤)   3、数据有效性验证
创建正则表达式的两种方式:  1)字面量或直接量: /js/igm   2)构造函数: new RegExp(变量名, 'igm')
模式修饰符:  1)g 全局匹配   2)i 忽略大小写   3)m 多行匹配
简单的转义字符: 1)\n 换行符  2)\t 制表符  3)\xnn 由十六进制数nn指定的拉丁字符(eg.\x0A<=>\n)   4)\uxxxx 由十六进制数xxxx指定的Unicode字符(eg.\u0009<=>\t)

<span class="text_flag">正则表达式的关键词汇说明:</span>
	1)字符类
		1、[…]和[^…] 方括号内的任意一个字符;
		2、. 除换行符之外的任意一个字符
		3、\w和\W 任何字母、数字以及下划线组成的一个字符;
		4、\d和\D 任何一个数字
		5、\s和\S 任何Unicode空白符(eg.空格、制表符、\n)

	2)重复(量词)
			1、{n,m}    n<=x<=m
			2、{n,}     x>=n
			3、{n}      x=n
			4、?        {0,1}
			5、+        {1,}
			6、*        {0,}

	3)非贪婪匹配
			1、{n,m}?
			2、{n,}?
			3、{n}?
			4、??
			5、+?
			6、*?

	4)选择、分组和引用
			1、| 选择,匹配该符号左边或右边的东西
			2、(…) 分组 统一操作;捕获括号中的内容
			3、(?:…) 非捕获性分组
			4、\n 第n个捕获性分组的引用 (eg.\1 \2 \3…)

	5)捕获到的内容
		1、exec返回的数组中
		2、/\1/ 模式中
		3、replace的第二个参数中，$1
		4、RegExp.$1

	6)指定匹配位置
		1、^ 首匹配
		2、$ 尾匹配
		3、\b和\B 单词边界，即\w和\W之间的位置
		4、(?=p)和(?!p) 前瞻性匹配,只有接下来的字符=p,才匹配之前的内容

<span class="text_flag">常用的特殊字符</span>
	1、\ 做为转义,如/b/匹配字符"b", /\b/匹配一个单词的边界
	2、^ 匹配一个输入或一行的开头，/^a/匹配"an A"，而不匹配"An a"
	3、$ 匹配一个输入或一行的结尾，/a$/匹配"An a"，而不匹配"an A"
	4、* 匹配前面元字符 0 次或多次，/ba*/可以匹配 b,ba,baa,baaa
	5、+ 匹配前面元字符 1 次或多次，/ba+/可以匹配 ba,baa,baaa
	6、? 匹配前面元字符 0 次或 1 次，/ba?/可以匹配 b,ba
	7、(x) 匹配 x 保存 x 在名为$1...$9 的变量中
	8、x|y 匹配 x 或 y
	9、{n} 精确匹配 n 次
	10、{n,} 匹配 n 次以上
	11、{n,m} 匹配 n-m 次
	12、[xyz] 字符集(character set)，匹配这个集合中的任一一个字符(或元字符)
	13、[^xyz] 不匹配这个集合中的任何一个字符
	14、[\b] 匹配一个退格符
	15、\b 匹配一个单词的边界
	16、\B 匹配一个单词的非边界
	17、\cX 这儿，X 是一个控制符，/\cM/匹配 Ctrl-M
	18、\d 匹配一个字数字符，/\d/ = /[0-9]/
	19、\D 匹配一个非字数字符，/\D/ = /[^0-9]/
	20、\n 匹配一个换行符
	21、\r 匹配一个回车符
	22、\s 匹配一个空白字符，包括\n,\r,\f,\t,\v 等
	23、\S 匹配一个非空白字符，等于/[^\n\f\r\t\v]/
	24、\t 匹配一个制表符
	25、\v 匹配一个重直制表符
	26、\w 等于[a-zA-Z0-9_]
	27、\W [^a-zA-Z0-9_]

<span class="text_flag">RegExp对象的实例方法</span>
	1、test(字符串)
	2、exec(字符串)  返回分组中匹配到的内容;返回当前匹配到的内容,而不是所有;(全局匹配时,lastIndex属性会往后移动)
			demo1: 匹配字符串'weekend,endfor,end'中所有的end,并分别打印出其中的字母e
					// 提示：1.全局匹配  2.exec循环打印
					var str = 'weekend,endfor,end';
					var pattern =/(e)nd/g;
					var result;
					while((result = pattern.exec(str)) != null) {
						console.log(result[1]);
					}
			demo2:
					var str = 'abcd';
					var pattern = /(?:ab)c/;
					console.log(pattern.exec(str));

	3、toString()、toLocaleString()、valueOf()
				demo1:
					var pattern = new RegExp('a\\nb')
					console.log(pattern.toString());
					console.log(pattern.toLocaleString());
					console.log(pattern.valueOf() === pattern);
	4、match:   只有非全局匹配,才会返回分组中匹配到的内容;全局匹配只会一次返回所有匹配到的字符。


	5、replace: 非全局匹配,只替换第一个匹配到的内容;全局匹配替换所有匹配到的内容; test、search、split;没区别

<span class="text_flag">RegExp对象的实例属性</span>
	1、global 是否设置了g
	2、ignoreCase 是否设置了i
	3、multiline 是否设置了m
	4、source 字面量形式对应的字符串
	5、lastIndex 开始搜索下一个匹配项的字符位置,默认0;(全局匹配模式下,会往后移动)
		demo1:
			var str = 'js js js';
			var pattern = /(j)s/;
			pattern.exec(str);
			console.log(RegExp.input);
			console.log(RegExp.$_); // 可接: $_  $1-9
			console.log(RegExp['$_']);
			console.log(RegExp.lastMatch);
			console.log(RegExp['$&']);
			console.log(RegExp.leftContext);
			console.log(RegExp['$`']);
			console.log(RegExp.rightContext);
			console.log(RegExp["$'"]);
			console.log(RegExp.lastParen);
			console.log(RegExp["$+"]);

<span class="text_flag">RegExp对象的构造函数属性</span>
	1、input 匹配的字符串
	2、lastMatch 最近一次的匹配项
	3、lastParen 最近一次匹配的捕获组
	4、leftContext 字符串中匹配到的内容之前的文本
	5、rightContext 字符串中匹配到的内容之后的文本
	6、$1~$9 第1~第9个匹配到的捕获组

<span class="text_flag">String对象和正则表达式相关的方法</span>
	1、search(正则或字符串)  //第一次出现的索引位置
				var str = 'html js js';
				var pattern = /js/g;
				console.log(str.search(pattern));
				console.log(str.search('js'));
	2、match(正则)
				demo1: 找出字符串'110报警120急救119火警114查询'中的所有数字,并打印出来; 提示: 1.全局匹配  2.match
					var str = '110报警120急救119火警114查询';
					var pattern =/\d+/g;
					console.log(str.match(pattern));
				demo2:
					var str = 'js js js';
					var pattern = /(j)s/;
					console.log(str.match(pattern)); //[js,j]
					var pattern = /(j)s/g; 			 //[js,js,js]
					console.log(str.match(pattern));

				demo3:
					var str = '1.js\n2.js\n3.js';
					var pattern = /js/m;
					console.log(str);
					console.log(str.match(pattern));
					var pattern = /js/mg;
					console.log(str.match(pattern));

	3、split(正则或字符串)
				demo1:
					var str = 'html ,   css  ,   js';
					var pattern = /\s*,\s*/;
					console.log(str.split(pattern));  // [html,css,js]
	4、replace(正则或字符串,替换成的文本或函数)
				demo1: 找出字符串'asdfgaaaafdgdgaaaadgsxcvcxva'中出现次数最多的字符，并打印出其出现的次数
					// 提示：1.利用数组排序 2.利用引用匹配相同的字符
					var str = 'asdfgaaaafdgdgaaaadgsxcvcxva';
					var arr = str.split(''); // 转换成数组
					str = arr.sort().join(''); // 排序之后再拼成字符串，此时相同的字符紧挨在了一起
					var value = ''; // 出现次数最多的字符
					var count = 0; // 出现次数
					var pattern =/(\w)\1+/g; // 匹配紧挨着的相同字符
					str.replace(pattern, function ($0, $1) {
						// $0表示匹配到的所有相同字符，$1表示第一个分组匹配的字符，也就是单个字符
						if (count < $0.length) {
						// 如果$0.length>count，就表示此时匹配到的字符，到目前为止是出现次数最多的
							count = $0.length;
							value = $1;
						}
					});
					console.log('出现次数最多的字符是：'+value+'，共出现'+count + '次');
				demo2:
					var str = 'I love js';
					var pattern = /(js)/;
					document.write(str.replace(pattern, '&lt;strong style="color: red;"&gt;$1&lt;/strong&gt;'));
				demo3: 按匹配的文本长度替换为*
						var str = '中国军队和阿扁一起办证';
						var pattern = /国军|阿扁|办证/g;
						console.log(str.replace(pattern, function ($0) {
							console.log($0);
							var result = '';
							for (var i = 0; i < $0.length; i++){ result += '*';}
							return result;
						}));
<span class="text_flag">常用的正则表达式</span>
	1、"^\d+$" //非负整数（正整数 + 0）
	2、"/[1-9]\d*/" //正整数
	3、"^((-\d+)|(0+))$” //非正整数（负整数 + 0）
	4、"^-[0-9]*[1-9][0-9]*$" //负整数
	5、"^-?\d+$" //整数
	6、"^\d+(\.\d+)?$" //非负数（正整数+正浮点数 + 0）
	7、"^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$"//正数
	8、"^((-\d+(\.\d+)?)|(0+(\.0+)?))$" //非正数（负数 + 0）
	9、"^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$" //负数
	10、"^(-?\d+)(\.\d+)?$" //实数
	11、"^[A-Za-z]+$" //由 26 个英文字母组成的字符串
	12、"^[A-Z]+$" //由 26 个英文字母的大写组成的字符串
	13、"^[a-z]+$" //由 26 个英文字母的小写组成的字符串
	14、"^[A-Za-z0-9]+$" //由数字和 26 个英文字母组成的字符串
	15、"^\w+$" //由数字、26 个英文字母或者下划线组成的字符串
	16、"^[a-zA-Z0-9]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$" //email 地址
	17、^(13)[0-9]{9}$|(147)[0-9]{8}$|(15)[0,1,2,3,5,6,7,8,9]{1}[0-9]{8}$|(18)[0,2,5,6,7,8,9]{1}[0-9]{8}$ //手机号码
	18、^[\w|@|!|&|*|#|$|^|?|!|~|+|=|-|\.|,]{6,18}$ //密码 6-18 位，包括数字字母或符号
	19、^[\u4e00-\u9fa5]{2,4}$ //中文名字，2-4 个字
	20、^[1-9]{1}[0-9]{14}$|^[1-9]{1}[0-9]{16}([0-9]|[xX])$ //身份证号
	21、^[1-9][0-9]{4,}$ //.匹配腾讯 QQ 号
	22、[1-9]\d{5}(?!\d) //匹配中国邮政编码


<span class="text_flag">常用demo</span>
demo1:请写出能够匹配任意一个字符的正则表达式; 提示:1.字符类和它相反的字符类加在一起就可以匹配所有字符
	/[\w\W]/ 或  /[\d\D]/ 或  /[\s\S]/ 或 /[^]/

demo2: 注册网站时,一般都需要填写用户名;现要求用户名可以包含:空格、中文、字母、数字以及下划线，请写出能与之匹配的正则表达式
	// 提示：1.将满足要求的全部写入[]中即可
	/[\u4e00-\u9fa5\sa-zA-Z0-9_]/  或 	/[\u4e00-\u9fa5\sa-z0-9_]/i 或 	/[\u4e00-\u9fa5\s\w]/

demo3:分别写出匹配正整数、负整数以及既能匹配正整数，也能匹配负整数的正则表达式
	// 提示：1.注意0是整数，不是正整数，也不是负整数
	正整数： /[1-9]\d*/
	负整数： /-[1-9]\d*/
	正整数和负整数：/-?[1-9]\d*/

demo4: 现有字符串'js[javascript];html[hyper text markup language];css[cascading style sheet];',
	// 请匹配第一个[]以及它里面的内容，不得直接用[javascript]匹配
	// 提示：1.注意贪婪的问题  2.[和]需要转义
	var str = 'js[javascript];html[hyper text markup language];css[cascading style sheet];';
	var pattern = /\[.*?\]/;
	console.log(pattern.exec(str));

<span class="text_flag">选择、分组和引用</span>
demo1: html标签的属性值既可以放在""中，也可以放在''中，例如&lt;p class="box" id='box'&gt;&lt;/p&gt;
	// 请写出既能匹配""中内容，又能够匹配''中内容的正则表达式; 提示：1.可以用选择的写法 2.保证前后所用引号的一致性
	/"[^"]*"|'[^']*'/  或者 	/(["'])[^"']\1/

demo2:指定匹配位置; 某网站注册需要实名认证，请写出验证用户输入的姓名是否合法的正则表达式
	// 提示：1.请使用首尾匹配 2.假设一般人的名字最少2个字，最多4个字
	/^[\u4e00-\u9fa5]{2,4}$/

demo3:现有字符串'Windows98, WindowsXP, Windows7'，请分别写出匹配后面是XP的Windows和后面不是7的Windows的两个正则表达式
	// 提示：1.前瞻性匹配和负向前瞻性匹配
	/Windows(?=XP)/
	/Windows(?!7)/
			</pre>
        </div>


    </div>
</div>
</body>
</html>